//上下拉刷新
import React, {} from 'react';
import {
  ListView,
  View,
  Text,
  Platform,
  StyleSheet,
  TouchableOpacity,
  RefreshControl,
} from 'react-native';

import {ObjUtils} from '../utils/Utils';
import SizeUtils from '../common/SizeUtils';
import ToastUtils from '../common/ToastUtils';
import TImage from './TImage';
import TComponent from './TComponent';

const REFRESH_HEADER_HEIGHT = 140;
const PAGE_SIZE = 10;

export const PullTitle=[" ", '下拉以刷新', '松开以刷新', '正在刷新数据'];
export const PullStatus={
  no:0,
  pullToDo:1,
  releaseToDo:2,
  doing:3,
}

export const LoadMoreTitle={
  pullToLoadMore:'上拉以加载',
  releaseToLoadMore:'松开以加载',
  loadMoring:'正在加载数据'
}

export const LoadMoreStatus={
  pullToLoadMore:0,
  releaseToLoadMore:1,
  loadMoring:2,
}

export default class TRefreshComponent extends TComponent {
  constructor(props) {
    super(props);

    this._ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

    this.state.dataSource = this._ds.cloneWithRows([]);
    this.state.pullStatus = 0;
    this.state.loadMoreTitle = "";
    this.state.loadMoreStatus = 0;
    this.state.showLoadMore = false;

    this._firstEnd = true;
    this._currentPage = 1;
    this._initTimer = null;
    this._initComplete = false;
    this._listView = null;
    this._offsetY = 0;
    this._loadMore = false;
    this._dragFlag = false; //是否处于拖动状态的标志
    this._refreshing = false;
    this._refreshTimer = null;//用来请求超时后修改状态
    this._refreshIntervalTimer = null; //用来控制请求的频率
    this._needToEnd = false;
    this._autoMove = false;
    this._useLoadMore = this.props.useLoadMore == null ? true : this.props.useLoadMore;
    this._useRefresh = this.props.useRefresh == null ? true : this.props.useRefresh;
    this._doRefreshMark = false;
    this._itemClickEnable = this.props.itemClickEnable === null ? true : this.props.itemClickEnable;

    this._allDatas = [];
    // this._allDatas = [{isNull:true}, {isNull:true}, {isNull:true}];

    if(this.props.style.width > 0) {
      this._width = this.props.style.width;
    }
    else {
      this._width = SizeUtils.getWindowSize().width;
    }
    this._contentHeight = this.props.style.height;
    this._headerHeight = 0;

    this._listViewTop = Platform.OS === "ios" ? -SizeUtils.translateDesignHeightToCode(REFRESH_HEADER_HEIGHT) : 0;
    this._refreshHeaderHeight = SizeUtils.translateDesignHeightToCode(REFRESH_HEADER_HEIGHT);
  }

  componentDidMount(){
    if(this.props.autoInitRequest == false) {
      this._initComplete = true;
    }
    else {
      this._initTimer = setTimeout(()=>{
       clearTimeout(this._initTimer)
       this._initComplete = true;
       this._onRefresh();
     }, 1000);
    }
  }

  componentWillUnmount() {
    this._clearRefreshTimer();
    this._clearRefreshIntervalTimer();
    this._initTimer && clearTimeout(this._initTimer);
  }

  componentDidUpdate(preProps, preState) {
    if(this._needToEnd) {
      var endTimer = setTimeout(()=>{
       clearTimeout(endTimer)
       this.scrollToEnd();
       this._needToEnd = false;
      }, 500);
    }
  }

  render() {
    return(
      <View style={[this.props.style, {flexDirection:"column"}]}>
        {this._renderLoadMore()}
        <ListView
          ref={(ref)=>{this._listView = ref}}
          style={{height:this.props.style.height}}
          contentContainerStyle={this._getContentContainerStyle()}
          onContentSizeChange = {this._onContentSizeChange.bind(this)}
          enableEmptySections={true}
          removeClippedSubviews={false}
          renderHeader={this._onRenderHeader.bind(this)}
          renderFooter={this._onRenderFooter.bind(this)}
          scrollEventThrottle={60}
          onScroll={this._onScroll.bind(this)}
          onScrollBeginDrag={(event)=>this._onScrollBeginDrag(event)}
          onScrollEndDrag={(event)=>this._onScrollEndDrag(event)}
          onEndReachedThreshold={20}
          overScrollMode={"always"}
          onEndReached={(event)=>this._onEndReached(event)}
          dataSource={this._getDataSource()}
          renderRow={this._onRenderItem.bind(this)}
          showsHorizontalScrollIndicator={false}  // 隐藏水平指示器
          showsVerticalScrollIndicator={false}    // 隐藏垂直指示器
          automaticallyAdjustContentInsets = {false}
          keyboardDismissMode = {this.props.keyboardDismissMode == null ? this.props.keyboardDismissMode : "on-drag"}
          keyboardShouldPersistTaps = {this.props.keyboardShouldPersistTaps == null ? this.props.keyboardShouldPersistTaps : "true"}
          refreshControl={Platform.OS === "android" ? this._getRefreshControl() : undefined}
        >
        </ListView>
      </View>
    )
  }

  _getRefreshControl() {
    return <RefreshControl
      refreshing={this.state.pullStatus > 0 && this._offsetY < 0}
      tintColor="#db3132"
      title={this._getPullTitle()}
      titleColor="#000000"
      colors={['#ffffff', '#ffffff', '#ffffff']}
      progressBackgroundColor="#db3132"
      onRefresh={this._onRefresh.bind(this)}
    />
  }

  _getContentContainerStyle() {
    if(this.props.isRowWrap === true) {
      return {flexDirection:"row", flexWrap:"wrap", alignItems:'flex-start'};
    }
    else {
      return {};
    }
  }

  _getPullTitle() {
    // console.log(PullTitle[this.state.pullStatus]);
    if(Platform.OS === "android") {
        return "";
    }
    else {
      return PullTitle[this.state.pullStatus];
    }
  }

  clear() {
    let dataSource = this._ds.cloneWithRows([]);
    this.setState({
      dataSource:dataSource,
    })
  }
  leave(){
    this._allDatas=[];
    let dataSource = this._ds.cloneWithRows([]);
    this.setState({
      dataSource:dataSource,
    })
  }
  doRefresh(params) {
    this._clearRefreshIntervalTimer();
    this._onRefresh(params);
    this._doRefreshMark = true;
  }

  scrollTo(params) {
    // console.log("do scrollTo", params);
    this._listView.scrollTo(params);
  }

  scrollToEnd() {
    this._autoMove = true;
    this._listView.scrollToEnd();
  }

  _getDataSource() {
    return this.state.dataSource;
  }

  _onContentSizeChange(contentWidth, contentHeight) {
    this._contentHeight = contentHeight;
  }

  _renderRefresh() {
    return (
      <View style={{width:this._width, height:this._refreshHeaderHeight,
          justifyContent:"center", position:"absolute", top:this._listViewTop,
          alignItems:"center", backgroundColor:"#00000000", borderWidth:0}}>
        {/* <TImage source={require("../../../resource/images/common/list_loading.png")} */}
            {/* style={{width:280, height:80}}/> */}
        <Text style={{color:"#373737",
          backgroundColor:"#00000000", borderWidth:0}}>{this._getPullTitle()}</Text>
      </View>
    )
  }

  _renderLoadMore() {
    return(
      <View style={{position:"absolute", width:this._width, bottom:SizeUtils.translateDesignHeightToCode(20),
          opacity:(this._useLoadMore && (this.state.showLoadMore || this.state.loadMoreStatus == LoadMoreStatus.loadMoring)) ? 1 : 0}}>
        <Text style={{textAlign:"center"}}>{this.state.loadMoreTitle}
        </Text>
      </View>
    )
  }

  _onRenderHeader() {
    return (
      <View style={{}} onLayout={this._onHeaderLayout.bind(this)}>
        {this._renderRefresh()}
        {this._callRenderHeader()}
      </View>
    )
  }

  _callRenderHeader() {
    if(this.props.onRenderHeader) {
      return this.props.onRenderHeader();
    }
    else {
      //要不然不显示下拉刷新
      return (
        <View style={{height:1}}>
        </View>
      )
    }
  }

  _onHeaderLayout(event) {
    this._headerHeight = event.nativeEvent.height;
  }

  _onRenderFooter() {
    if(this.props.onRenderFooter) {
      return (
        <View onLayout={this._onFooterLayout.bind(this)}>
          {this.props.onRenderFooter()}
        </View>
      )
    }
  }

  _onFooterLayout(event) {

  }

  _onRenderItem(data, key, index) {
    if(!data || data.isNull) {
      return (
        <View style={{backgroundColor:this.props.isTR?"#fff0":"#ffffff", height:SizeUtils.translateDesignHeightToCode(100)}}>
        </View>
      );
    }
    else {
      return (
        <TouchableOpacity style={{backgroundColor:this.props.isTR?"#fff0":"#ffffff"}} overflow={"hidden"}
            onPress={()=>{this._onPressItem(data)}} disabled={this._itemClickEnable === false}>
          {this.props.onRenderItem(data, parseInt(index))}
        </TouchableOpacity>
      );
    }
  }

  _onPressItem(data) {
    // if(!data.isNull && data != "") {
      this.props.onPressItem(data);
    // }
  }

  _onRefresh(params) {
    this._doRefreshMark = false;
    if(this._useRefresh && this.props.onRefresh && this._initComplete && !this._refreshing) {
      if((!params || !params.force) && this._refreshIntervalTimer) {
        // ToastUtils.show("客官你刷新太频繁了...");
        return false;
      }
      this._refreshIntervalTimer = setTimeout(() => {
        this._clearRefreshIntervalTimer();
      }, this.props.refreshInterval ? this.props.refreshInterval : 1000);
      this._refreshing = true
      this.setState({
        pullStatus:PullStatus.doing
      })
      if(!params || params.scroll != false) {
        // this.scrollTo({x:0,y:0,animated:true});
      }
      this._currentPage = 1;
      this._doSendRefresh(1);
      return true;
    }
    return false;
  }

  _doSendRefresh(page) {
    this.props.onRefresh(page);
    this._refreshTimer = setTimeout(() => {
      this._clearRefreshTimer();
      this._onFinish(2);
    }, 5000);
  }

  _clearRefreshIntervalTimer() {
    this._refreshIntervalTimer && clearTimeout(this._refreshIntervalTimer);
    this._refreshIntervalTimer = null;
  }

  /**
   * 滑动中
   * @param event
   * @private
   */
  _onScroll(event){
    let y = event.nativeEvent.contentOffset.y
    this._offsetY = y
    // console.log("_onScroll", y, this.props.style.height);
    if (this._dragFlag){
      if (!this._refreshing){
        if (y <= -this._refreshHeaderHeight){
          //松开以刷新
          this.setState({
            pullStatus:PullStatus.releaseToDo,
          })
        }
        else if(y < 0){
          //下拉以刷新
          this.setState({
            pullStatus:PullStatus.pullToDo,
          })
        }
      }
    }
    if(this._contentHeight > this.props.style.height && this._offsetY > (this._contentHeight - this.props.style.height)) {
      this.setState({
        showLoadMore: true,
      })
    }
    else if (this.state.showLoadMore) {
      this.setState({
        showLoadMore: false,
      })
    }
    if(this.props.onScroll) {
      this.props.onScroll(event);
    }
  }

  /**
   * 拖拽
   * @private
   */
  _onScrollEndDrag(event){
    this._dragFlag = false;
    let y = event.nativeEvent.contentOffset.y
    this._offsetY = y
    if (!this._refreshing){
      if (this.state.pullStatus == PullStatus.releaseToDo){
        let result = this._onRefresh();
        if(!result) return;
        if (y <= 0) {
          this.scrollTo({x:0,y:-this._refreshHeaderHeight,animated:true});
        }
      }
      else if (this.state.pullStatus == PullStatus.pullToDo){
        this.scrollTo({x:0,y:0,animated:true});
        this.setState({
          pullStatus:PullStatus.no,
        })
      }
    }
  }

  _onScrollBeginDrag(event){
    this._dragFlag = true;
    this._autoMove = false;
    this._offsetY = event.nativeEvent.contentOffset.y;
  }

  /**
   * 刷新结束
   * @private
   */
  _onRefreshEnd(loadMoreStatus, noData, params){
    // console.log("_onRefreshEnd", loadMoreStatus, noData);
    this._clearRefreshTimer();
    this._refreshing = false
    //下拉以刷新
    this.setState({
      pullStatus:PullStatus.no,
    })
    if(loadMoreStatus != LoadMoreStatus.loadMoring) {
      if(this._listView.scrollProperties.offset < 0) {
        if(!params || params.scroll != false) {
          this.scrollTo({x:0,y:0,animated:true});
        }
      }
    }
    else if(loadMoreStatus == LoadMoreStatus.loadMoring && noData){
      this.scrollTo({x:0,y:(this._contentHeight - this.props.style.height),animated:true});
    }
  }

  _onEndReached(event) {
    if(this._useLoadMore === true && this._allDatas.length > 0 && !this._refreshing && this._initComplete &&
       (!this.props.style.height || this._contentHeight > this.props.style.height) && this._autoMove == false) {
      if(this._refreshIntervalTimer) {
        // ToastUtils.show("刷新太频繁");
        return;
      }
      this._refreshing = true;
      this._loadMore = true;

      this._refreshIntervalTimer = setTimeout(() => {
        this._clearRefreshIntervalTimer();
      }, this.props.refreshInterval ? this.props.refreshInterval : 1000);

      this.setState({
        loadMoreStatus:LoadMoreStatus.loadMoring,
        loadMoreTitle:LoadMoreTitle.loadMoring,
      })
      //0-9 1
      //10-19 2
      //20-29 3
      var page = parseInt(this._allDatas.length / PAGE_SIZE) + 1;
      this._doSendRefresh(page);
    }
  }

  _clearRefreshTimer() {
    this._refreshTimer && clearTimeout(this._refreshTimer);
    this._refreshTimer = null;
  }

  finish(type, data, params) {
    this._onFinish(type, data, params);
  }

  getData() {
    return this._allDatas;
  }

  _onFinish(type, data, params) {
    if (type==2) {return;}
    if(this._refreshing) {
      let dataSource = null;
      var loadMoreStatus = this.state.loadMoreStatus;
      if(type == 1 && data != null) {
        if(this.props.autoClearData === false) {
          dataSource = this._dealDatas(data);
        }
        else {
          dataSource = this._dealDatasAutoClear(data);
        }
        this._needToEnd = params && params.toEnd;
        this.setState({
          dataSource:dataSource,
          loadMoreStatus:LoadMoreStatus.pullToLoadMore,
          loadMoreTitle:LoadMoreTitle.pullToLoadMore,
        })
      }
      else {
        this.setState({
          loadMoreStatus:LoadMoreStatus.pullToLoadMore,
          loadMoreTitle:LoadMoreTitle.pullToLoadMore,
        })
      }
      this._onRefreshEnd(loadMoreStatus, type == 2 || data == null ||data.length == 0, params);
    }
  }

  _dealDatas(data) {

  }

  _dealDatasAutoClear(data) {
    if(this.state.loadMoreStatus == LoadMoreStatus.loadMoring) {
      this._allDatas = ObjUtils.concatArrayNoRepeat(this._allDatas, data, this.props.dataKey);
      // this._allDatas = this._allDatas.concat(data);
      //0-10  1
      //11-20 2
      if(this._allDatas.length <= PAGE_SIZE) {
        this._currentPage = 1;
        this._allDatas = data;
      }
      else {
        this._currentPage = parseInt(this._allDatas.length / PAGE_SIZE);
      }
    }
    else {
      this._allDatas = data;
      this._currentPage = 1;
    }
    // let tempData = Array.from(this._allDatas);
    // while(tempData.length < 3) {
      // tempData.push("");
    // }
    // dataSource = this._ds.cloneWithRows(tempData);
    dataSource = this._ds.cloneWithRows(this._allDatas);
    return dataSource;
  }
}
